# lighting_effects.py

import cv2
import numpy as np
import math
from PIL import Image, ImageEnhance
def add_highlight_or_shadow(image, intensity=0.5, position="top-left"):
    """
    在图像中添加高光或阴影
    """
    mask = np.zeros_like(image, dtype=np.float32)
    h, w = image.shape[:2]
    center_positions = {
        "top-left": (0, 0),
        "top-right": (w, 0),
        "bottom-left": (0, h),
        "bottom-right": (w, h)
    }
    center = center_positions.get(position, (w // 2, h // 2))

    cv2.circle(mask, center, max(h, w) // 2, (255, 255, 255), -1)
    mask = cv2.GaussianBlur(mask, (51, 51), 0)
    mask = mask / 255.0 * intensity  # 控制强度
    result = cv2.addWeighted(image.astype(np.float32), 1 - intensity, mask, intensity, 0)
    return cv2.convertScaleAbs(result)


def simulate_low_light(image, scale=0.5):
    """
    模拟低光条件
    """
    result = cv2.convertScaleAbs(image, alpha=scale, beta=0)
    return result


def simulate_directional_light(image, angle, intensity=1.0):
    """
    模拟特定方向光源
    :param image: 输入图像
    :param angle: 光源方向角度 (0-360)
    :param intensity: 光照强度 (0.5-2.0)
    :return: 添加光源效果的图像
    """
    rows, cols = image.shape[:2]
    gradient = np.zeros((rows, cols), dtype=np.float32)

    # 光源位置 (根据角度)
    x_start = int(cols / 2 + np.cos(np.radians(angle)) * cols / 2)
    y_start = int(rows / 2 - np.sin(np.radians(angle)) * rows / 2)

    # 创建光照渐变
    for i in range(rows):
        for j in range(cols):
            distance = np.sqrt((j - x_start)**2 + (i - y_start)**2)
            gradient[i, j] = max(0, 1 - distance / max(rows, cols))

    # 调整强度并叠加光照效果
    gradient = gradient * intensity
    gradient = np.clip(gradient, 0, 1)
    overlay = cv2.merge((gradient, gradient, gradient))
    result = cv2.addWeighted(image.astype(np.float32) / 255, 1, overlay, intensity, 0)
    return (result * 255).astype(np.uint8)

def simulate_lighting(image, light_angle, light_radius, brightness):
    # 调整图像的亮度
    image = cv2.convertScaleAbs(image, alpha=brightness)

    # 创建一个灰度图像作为光照层
    height, width, _ = image.shape
    light_layer = np.zeros((height, width), dtype=np.float32)

    # 计算光源位置
    light_x = int(width / 2 + light_radius * math.cos(math.radians(light_angle)))
    light_y = int(height / 2 + light_radius * math.sin(math.radians(light_angle)))

    # 计算距离光源圆心的距离
    y, x = np.ogrid[:height, :width]
    dist_from_center = np.sqrt((x - light_x) ** 2 + (y - light_y) ** 2)

    # 根据距离计算光照强度的渐变
    intensity = 1 - np.clip(dist_from_center / light_radius, 0, 1)

    # 将光照强度映射到灰度图像上
    light_layer = (intensity * 255).astype(np.uint8)

    # 将光照层应用到原始图像上
    result = cv2.add(image, cv2.cvtColor(light_layer, cv2.COLOR_GRAY2BGR))

    return result

def add_noise(image, noise_level):
    # 生成噪声
    noise = np.random.normal(0, noise_level, image.shape)
    noisy_image = image + noise

    # 将噪声图像裁剪到有效范围
    noisy_image = np.clip(noisy_image, 0, 255).astype(np.uint8)
    return noisy_image

def add_gaussian_blur(image, kernel_size):
    return cv2.GaussianBlur(image, kernel_size, 0)